package il.ac.tau.arielgue.outxing;

import il.ac.tau.arielgue.outxing.agents.FAOOrganism;
import il.ac.tau.arielgue.outxing.contexts.DemeSubContext;
import il.ac.tau.arielgue.outxing.contexts.OutXingContext;
import il.ac.tau.arielgue.outxing.helpers.FAOTransformation;
import il.ac.tau.arielgue.outxing.helpers.UniformTransformation;
import il.ac.tau.arielgue.outxing.utils.Params;
import proevolution.AbstractTransformationContextBuilder;
import proevolution.agents.Organism;
import proevolution.helpers.OrganismTransformation;
import repast.simphony.context.Context;
import repast.simphony.dataLoader.ContextBuilder;
import repast.simphony.parameter.IllegalParameterException;
import simphony.util.messages.MessageCenter;

/**
 * Builds an outxing organism context but transforms part of the population to
 * {@link FAOOrganism}.
 * 
 * @author ariel
 * 
 */
public class FAOContextBuilder extends AbstractTransformationContextBuilder {

	protected static final MessageCenter logger = MessageCenter
			.getMessageCenter(FAOContextBuilder.class);

	private OrganismTransformation transformation = null;

	@SuppressWarnings("unchecked")
	@Override
	public Context<Organism> build(Context<Organism> context) {
		context = getInternalContextBuilder().build(context);

		if (context instanceof OutXingContext) {
			if (getTransformationFrequency() > 0) {
				OutXingContext mycontext = (OutXingContext) context;
				for (DemeSubContext deme : mycontext.getDemes()) {
					System.out.println("Transforming deme "+deme.getId());
					transformContext(deme);
				}
				transformContext(mycontext.getPool());
			}
		} else {
			throw new IllegalArgumentException("Context must be of type "
					+ OutXingContext.class.getName() + ", but it is of type "
					+ context.getClass().getName());
		}
		return context;
	}

	@Override
	protected double getTransformationFrequency() {
		return Params.getInvasionRate();
	}

	@Override
	protected OrganismTransformation getTransformation() {
		if (transformation == null) {
			if (Params.getInvader().equals("FAO")) {
				transformation = new FAOTransformation();
			} else if (Params.getInvader().equalsIgnoreCase("Uniform")) {
				transformation = new UniformTransformation();
			} else {
				throw new IllegalParameterException(
						"Parameter 'invader' must be either 'FAO' or 'Uniform', but it is '"
								+ Params.getInvader() + "'.");
			}
		}
		return transformation;
	}

	@Override
	protected ContextBuilder<Organism> getInternalContextBuilder() {
		return new OutXingContextBuilder();
	}
}
